﻿#region namespaces

using System;
using System.Diagnostics;
using System.Linq;
using Tools.BaseX;

#endregion

namespace ZOIL.DataBackend.BaseX
{
    public sealed partial class Database
    {
        internal Database(DatabaseConfiguration dbConfig)
        {
            if (dbConfig == null)
            {
                throw new ArgumentNullException("dbConfig");
            }

            DbConfig = dbConfig;

            _client = new BaseXClient(DbConfig.Host, DbConfig.Port, DbConfig.Username, DbConfig.Password, DbConfig.DatabaseName);
            CreateDatabaseIfNecessary();
            StartWatchingEventsFromDatabase();
        }

        /// <summary>
        ///     Creates the used database if it does not exist yet
        ///     Uses database name <see cref="DatabaseName" /> (ergo the database name passed into the c'tor, ergo
        ///     <see
        ///         cref="DbConfig" />
        ///     )
        ///     Creates the database with one document
        /// </summary>
        private void CreateDatabaseIfNecessary()
        {
            if (!_client.DatabaseExists(DatabaseName))
            {
                Logger.Info("Create new database {0}", DbConfig.DatabaseName);
                Debug.WriteLine(string.Format("Create new database {0}", DbConfig.DatabaseName));
                //leere db erstellen
                //updindex
                {
                    _client.ExecuteCommandUsingSessionWithoutContext("SET UPDINDEX " + DbConfig.UseUpdIndex);
                    Debug.WriteLine("Creating database " + (DbConfig.UseUpdIndex ? string.Empty : "without ") + "using UPDINDEX");
                }
                _client.CreateDatabase(DatabaseName, "");
                if (DbConfig.UseUpdIndex)
                {
                    _client.ExecuteCommand("SET UPDINDEX false");
                }
                //id-counter wird bei bedarf & verwendung erstellt
            }
            if (!_client.GetEvents().Contains(DbConfig.EventName))
            {
                Logger.Info("Create new event {0}", DbConfig.EventName);
                Debug.WriteLine(string.Format("Create new event {0}", DbConfig.EventName));
                _client.CreateEvent(DbConfig.EventName);
            }
        }

        /// <summary>
        ///     Deletes the created database
        ///     For Unit Tests
        /// </summary>
        internal void CleanUp()
        {
            try
            {
                _client.DropDatabase(DbConfig.DatabaseName);
            }
            catch (Exception e)
            {
                Logger.TraceException(string.Format("Failed to drop database {0}: {1}", DbConfig.DatabaseName, e.Message), e);
            }
            try
            {
                _client.DropEvent(DbConfig.EventName);
            }
            catch (Exception e)
            {
                Logger.TraceException(string.Format("Failed to drop event {0}: {1}", DbConfig.EventName, e.Message), e);
            }
        }
    }
}